/*
 * {comment of class}
 *
 * @author (C) <a href="http://www.carfield.com.hk">Carfield Yim</a>, 2005
 */
package hk.com.carfield.core;

import hk.com.carfield.util.LogUtil;
import hk.com.carfield.util.StringUtil;
import hk.com.carfield.util.TimeUtil;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.lang.exception.ExceptionUtils;

public final class MailManager {

    private final int port;

    private final String host;

    private final String email;

    public MailManager(int p, String h, String s) {
        port = p;
        host = h;
        email = s;
    }

    public boolean send(final String subject, final String body) {
        if (canSend() && StringUtil.notBlank(host)) {
            return sendNow(subject, body);
        }
        return false;
    }

    public boolean sendNow(final String subject, final String body) {
        try {
            final Properties props = System.getProperties();
            props.put("mail.smtp.host", host);
            props.put("mail.smtp.port", String.valueOf(port));
            final Session session = Session.getDefaultInstance(props, null);
            final MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(email));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
            message.setSubject(subject);
            message.setText(body, "UTF-8");
            // Send message
            Transport.send(message);
            return true;
        } catch (Exception e) {
            LogUtil.log(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }

    private final AtomicInteger counter = new AtomicInteger();

    private final AtomicLong lastReset = new AtomicLong(TimeUtil.currentTime());

    private final long resetPeriod = 10 * TimeUtil.MIN; // 10 min in milisecond

    /**
     * Prevent spamming myself
     */
    public boolean canSend() {
        counter.getAndIncrement();
        final long now = TimeUtil.currentTime();
        if (now - lastReset.get() > resetPeriod) {
            counter.set(0);
            lastReset.set(now);
        }

        return (counter.get() <= 5) ? true : false;
    }

	public void handleMap(String subject, final Map<String, AtomicInteger> map) {
		final TreeMap<String, AtomicInteger> newMap = sortMapByValue(map);
		final StringBuilder sb = new StringBuilder();
		for (Iterator<Entry<String, AtomicInteger>> iter = newMap.entrySet().iterator(); iter.hasNext();) {
			final Entry<String, AtomicInteger> entry = iter.next();
			sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");			
		}
		map.clear();
		send(subject, sb.toString());
	}

	public static TreeMap<String, AtomicInteger> sortMapByValue(final Map<String, AtomicInteger> map) {
		final TreeMap<String, AtomicInteger> newMap = new TreeMap<String, AtomicInteger>(new Comparator<String>() {
			public int compare(String o1, String o2) {
				return new Integer(map.get(o2).get()).compareTo(new Integer(map.get(o1).get()));
			}
		});
		newMap.putAll(map);
		return newMap;
	}
}
